#include "./hash-map.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

HashMap *createHashMap()
{
	HashMap *map = (HashMap *)malloc(sizeof(HashMap));
	map->count = 0;
	int i;
	// 分配空间，key中全部置为空键
	for (i = 0; i < HASH_SIZE; i++)
	{
		map->key[i] = (char *)calloc(64, sizeof(char));
		map->value[i] = (char *)calloc(64, sizeof(char));
		strcpy(map->key[i], NULL_KEY);
	}
	return map;
}

int hash(char key[])
{
	// 计算字符串总值
	int total = 0;
	char *str;
	for (str = key; *str != '\0'; str++)
	{
		total += (int)*str;
	}
	// 除数留余法
	return total % HASH_SIZE;
}

int reAddress(int address)
{
	return (address + 1) % HASH_SIZE;
}

int keyAddress(HashMap *map, char key[])
{
	if (map->count == 0)
	{
		return -1;
	}
	// 先求地址
	int address = hash(key);
	// 记录原始地址
	int originAddress = address;
	// 查看对应地址的键和这个键是否一致，不一致说明冲突，使用开放定址法再探测
	while (strcmp(map->key[address], key) != 0)
	{
		// 重定址
		address = reAddress(address);
		// 若得到空键或者回到原点说明这个键不存在
		if (strcmp(map->key[address], NULL_KEY) == 0 || address == originAddress)
		{
			return -1;
		}
	}
	return address;
}

void putMap(HashMap *map, char key[], char value[])
{
	if (map->count == HASH_SIZE)
	{
		printf("哈希表满！\n");
		return;
	}
	// 求地址
	int address = hash(key);
	// 如果冲突了，使用开放定址法重新计算地址
	while (strcmp(map->key[address], NULL_KEY) != 0)
	{
		address = reAddress(address);
	}
	// 然后找到空位插入键值对
	strcpy(map->key[address], key);
	strcpy(map->value[address], value);
	map->count++;
}

char *getMap(HashMap *map, char key[])
{
	// 求地址
	int address = keyAddress(map, key);
	if (address == -1)
	{
		printf("键不存在！\n");
		return NULL;
	}
	return map->value[address];
}

void removeKeyValue(HashMap *map, char key[])
{
	// 求地址
	int address = keyAddress(map, key);
	if (address != -1)
	{
		strcpy(map->key[address], NULL_KEY);
		map->count--;
	}
}